<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
    <title>
        FeatureLayer 中的基本查询 |样品 |适用于 JavaScript 4.18 的 ArcGIS API
    </title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.18/esri/themes/light/main.css"/>
    <script src="https://js.arcgis.com/4.18/"></script>

    <style>
        html,
        body,
        #viewDiv {
            height: 100%;
            width: 100%;
            margin: 0;
            padding: 0;
        }
        #optionsDiv {
            background-color: white;
            color: black;
            padding: 6px;
            max-width: 400px;
        }
    </style>
    <script>
        require([
            "esri/Map",
            "esri/Graphic",
            "esri/views/MapView",
            "esri/layers/FeatureLayer",
            "esri/widgets/Legend"
        ], function (Map, Graphic, MapView, FeatureLayer, Legend) {
            let layer = new FeatureLayer({
                portalItem: {
                    id: "234d2e3f6f554e0e84757662469c26d3"
                },
                outFields: ["*"]
            });

            let map = new Map({
                basemap: "gray-vector",
                layers: [layer]
            });

            let view = new MapView({
                container: "viewDiv",
                map: map,
                popup: {
                    //此属性向 Popup 指示它需要允许或禁止单击事件传播
                    autoOpenEnabled: false,
                    //指示弹出窗口的位置是否停靠在视图的一侧
                    dockEnabled: true,
                    //停靠弹出窗口可以提供更好的用户体验，尤其是在移动设备上的应用程序中打开弹出窗口时
                    dockOptions: {
                        //如果true，则显示停靠按钮。如果false，则从弹出窗口中隐藏停靠按钮
                        buttonEnabled: false,
                        //定义停靠弹出窗口的视图的尺寸。设置为false在断点处禁用停靠
                        breakpoint: false,
                        //弹窗的位置
                        position: "bottom-right"
                    }
                }
            });

            let legend = new Legend({
                view: view,
                layerInfos: [
                    {
                        layer: layer
                    }
                ]
            });

            view.ui.add(legend, "bottom-left");
            view.ui.add("optionsDiv", "top-right");

            // 对于基本查询，附加查询字段最初设置为 null
            let distance = null;
            let units = null;

            //为鼠标点击创建图形
            let pointGraphic = new Graphic({
                symbol: {
                    type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
                    color: [0, 0, 139],
                    outline: {
                        color: [255, 255, 255],
                        width: 1.5
                    }
                }
            });

            //为距离缓冲区创建图形
            let bufferGraphic = new Graphic({
                symbol: {
                    type: "simple-fill", // autocasts as new SimpleFillSymbol()
                    color: [173, 216, 230, 0.2],
                    outline: {
                        // autocasts as new SimpleLineSymbol()
                        color: [255, 255, 255],
                        width: 1
                    }
                }
            });

            //当查询类型改变时，设置适当的值
            let queryOpts = document.getElementById("query-type");

            queryOpts.addEventListener("change", function () {
                switch (queryOpts.value) {
                    //为距离查询设置的值
                    case "distance":
                        distance = 0.5;
                        units = "miles";
                        break;
                    default:
                        //默认设置为基本查询
                        distance = null;
                        units = null;
                }
            });
            layer.load().then(function () {
                //将视图范围设置为数据范围
                view.extent = layer.fullExtent;
                layer.popupTemplate = layer.createPopupTemplate();
            });

            view.on("click", function (event) {
                view.graphics.remove(pointGraphic);
                if (view.graphics.includes(bufferGraphic)) {
                    view.graphics.remove(bufferGraphic);
                }
                queryFeatures(event);
            });


            //查询方法
            function queryFeatures(screenPoint) {
                //将屏幕点转为地图点
                const point = view.toMap(screenPoint);
                //对要素服务执行Query并返回FeatureSet
                layer.queryFeatures({
                        geometry: point,//应用于空间过滤器的几何
                        distance: distance,//在空间查询中指定距给定几何的搜索距离
                        units: units,//在空间查询中指定距离时计算缓冲区距离的单位
                        spatialRelationship: "intersects",//对于空间查询，此参数定义了查询图层或图层视图中的要素与输入几何的空间关系
                        returnGeometry: false,//如果为 true，则返回的 FeatureSet 中的每个要素都包含几何
                        returnQueryGeometry: true,//如果为 true，则查询几何将与查询结果一起返回
                        outFields: ["*"]
                    })
                    .then(function (featureSet) {
                        //将图形位置设置为鼠标指针并添加到地图视图
                        pointGraphic.geometry = point;
                        view.graphics.add(pointGraphic);
                        //打开查询结果弹窗
                        view.popup.open({
                            location: point,
                            features: featureSet.features,
                            featureMenuOpen: true
                        });
                        if (featureSet.queryGeometry) {
                            bufferGraphic.geometry = featureSet.queryGeometry;
                            view.graphics.add(bufferGraphic);
                        }
                    });
            }
        });
    </script>
</head>
<body>
<div id="viewDiv"></div>
<div id="optionsDiv" class="esri-widget">
    <p>
        选择查询类型并单击地图上的一个点以查看结果
    </p>
    <select id="query-type" class="esri-widget">
        <option value="basic">基本查询</option>
        <option value="distance">按距离查询</option>
    </select>
</div>
</body>
</html>
